package com.media_server.service;

import cn.hutool.core.io.IoUtil;
import com.j256.simplemagic.ContentInfo;
import com.j256.simplemagic.ContentInfoUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;

import java.io.*;
import java.time.LocalDateTime;
import java.util.UUID;

@Slf4j
public abstract class AbstractMediaService implements MediaService {

    public final String DEFAULT_MEDIA_TYPE = "application/octet-stream";

    public abstract String getBucket(String contentType);

    /**
     * 获取当前日期文件夹 用于为文件保存的目录路径
     *
     * @return 文件保存的目录路径
     */
    protected static String getDirectory() {
        LocalDateTime localDateTime = LocalDateTime.now();
        // 获取当前年份
        int year = localDateTime.getYear();
        // 获取当前月份
        int month = localDateTime.getMonthValue();
        // 获取当前日期
        int day = localDateTime.getDayOfMonth();
        return year + "/" + month + "/" + day + "/";
    }

    /**
     * 校验文件完整性
     *
     * @param originFileMd5  原始文件的MD5值
     * @param targetFilePath 目标文件路径
     * @return true:校验成功 false:校验失败
     */
    protected String validateFileIntegrity(String originFileMd5, String targetFilePath) throws IOException {
        InputStream targetFileInputStream = new FileInputStream(targetFilePath);
        try {
            if (originFileMd5.equals(DigestUtils.md5Hex(targetFileInputStream))) {
                return originFileMd5;
            }
            return null;
        } finally {
            IoUtil.close(targetFileInputStream);
        }
    }

    protected String validateFileIntegrity(File originFile , File targetFile) throws IOException {
        // 原始文件流
        InputStream originalStream = new FileInputStream(originFile);
        // 目标文件流
        InputStream targetStream = new FileInputStream(targetFile);
        return validateFileIntegrity(originalStream,targetStream);
    }

    protected String validateFileIntegrity(InputStream originStream, InputStream targetStream) throws IOException {
        try {
            String originMd5 = DigestUtils.md5Hex(originStream);
            String targetMd5 = DigestUtils.md5Hex(targetStream);
            if (originMd5.equals(targetMd5)) {
                return originMd5;
            }
            return null;
        } finally {
            IoUtil.close(originStream);
            IoUtil.close(targetStream);
        }
    }

    /**
     * 将文件下载到本地 返回本地文件路径
     *
     * @param inputStream 用户传递的文件流
     * @return 本地文件路径
     */
    protected File download(InputStream inputStream) {
        return download(inputStream, null , ".temp");
    }

    protected File download(InputStream inputStream, File file) {
        return download(inputStream, file,".temp");
    }

    protected File download(InputStream inputStream, String suffix) {
        return download(inputStream, null , suffix);
    }

    protected File download(InputStream inputStream, File file, String suffix) {
        try {
            if (file == null) {
                file = File.createTempFile(UUID.randomUUID().toString(), suffix);
            }
            // 将用户传递的文件写出到本地
            OutputStream outputStream = new FileOutputStream(file);
            IoUtil.copy(inputStream, outputStream);
            IoUtil.close(outputStream);
            IoUtil.close(inputStream);
            return file; // 返回文件信息
        } catch (IOException e) {
            log.error("文件下载到本地异常：{}", e.getMessage());
            throw new RuntimeException(e);
        }
    }

    /**
     * 递归删除目录及其所有内容
     *
     * @param directory 要删除的目录
     * @return true: 删除成功 false: 删除失败
     */
    public boolean deleteDirectoryRecursively(File directory) {
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    if (!deleteDirectoryRecursively(file)) {
                        return false;
                    }
                } else {
                    if (!file.delete()) {
                        log.error("删除文件失败: {}", file.getAbsolutePath());
                        return false;
                    }
                }
            }
        }
        if (!directory.delete()) {
            log.error("删除目录失败: {}", directory.getAbsolutePath());
            return false;
        }
        return true;
    }

    /**
     * 将文件字节数转换为 MB
     */
    public double getFileSizeInMB(long size) {
        return size / (1024.0 * 1024.0);
    }

    /**
     * 获取文件后缀
     *
     * @param fileName 文件名
     * @return 文件后缀
     */
    public String getFileSuffix(String fileName) {
        if (fileName == null) {
            return "";
        }
        int lastIndexOf = fileName.lastIndexOf(".");
        return fileName.substring(lastIndexOf);
    }

    /**
     * 获取文件类型
     *
     * @param fileSuffix 文件后缀
     * @return 文件类型
     */
    public String getFileContentType(String fileSuffix) {
        if (fileSuffix == null) {
            fileSuffix = "";
        }
        ContentInfo suffixName = ContentInfoUtil.findExtensionMatch(fileSuffix);
        String defaultContentType = this.DEFAULT_MEDIA_TYPE;   // 默认类型
        if (suffixName != null) {
            defaultContentType = suffixName.getMimeType();
        }
        return defaultContentType;
    }

}
